﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Collections;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.IO;

namespace FrasesSimpsonsMvc.Views
{
    public enum VideoProvider
    {
        YouTube,
        Tinypic,
        Facebook,
        Unknown
    }

    public static class HtmlHelperExtensions
    {

        private static string BasicEmbedFormat = "<a href=\"{0}\" alt=\"Video\">{0}</a>";
        
        private static string YoutubeUrlFormat = "http://www.youtube.com/v/{0}?version=3";
        private static string YoutubeEmbedFormat = "<object width=\"{2}\" height=\"{3}\"><param name=\"movie\" value=\"http://www.youtube.com/v/{0}?fs=1&amp;hl=en_US&amp;rel=0\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://www.youtube.com/v/{0}?fs=1&amp;hl=en_US&amp;rel=0\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"{2}\" height=\"{3}\"></embed></object><br/><a href=\"{1}\" target=\"_blank\" alt=\"Video\">{1}</a>";
        private static string YoutubeEmbedAutoplayFormat = "<object width=\"{2}\" height=\"{3}\"><param name=\"movie\" value=\"http://www.youtube.com/v/{0}?fs=1&amp;hl=en_US&amp;rel=0&autoplay=1\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://www.youtube.com/v/{0}?fs=1&amp;hl=en_US&amp;rel=0&autoplay=1\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"{2}\" height=\"{3}\" wmode=\"transparent\"></embed></object><br/><a href=\"{1}\" target=\"_blank\" alt=\"Video\">{1}</a>";
        private static string YoutubeCleanEmbedFormat = "<object width=\"{2}\" height=\"{3}\"><param name=\"movie\" value=\"http://www.youtube.com/v/{0}?fs=1&amp;hl=en_US&amp;rel=0\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://www.youtube.com/v/{0}?fs=1&amp;hl=en_US&amp;rel=0\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"{2}\" height=\"{3}\"></embed></object>";
        
        private static string TinypicUrlFormat = "http://v4.tinypic.com/player.swf?file={0}&s=4";
        private static string TinypicEmbedFormat = "<object width=\"{2}\" height=\"{3}\"><param name=\"movie\" value=\"http://v4.tinypic.com/player.swf?file={0}&s=4\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://v4.tinypic.com/player.swf?file={0}&s=4\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"{2}\" height=\"{3}\"></embed></object><br/><a href=\"{1}\" target=\"_blank\" alt=\"Video\">{1}</a>";
        private static string TinypicCleanEmbedFormat = "<object width=\"{2}\" height=\"{3}\"><param name=\"movie\" value=\"http://v4.tinypic.com/player.swf?file={0}&s=4\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://v4.tinypic.com/player.swf?file={0}&s=4\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"{2}\" height=\"{3}\"></embed></object>";

        private static string FacebookUrlFormat = "http://www.facebook.com/v/{0}";
        private static string FacebookEmbedFormat = "<object width=\"{2}\" height=\"{3}\"><param name=\"allowfullscreen\" value=\"true\" /><param name=\"allowscriptaccess\" value=\"always\" /><param name=\"movie\" value=\"http://www.facebook.com/v/{0}\" /><embed src=\"http://www.facebook.com/v/{0}\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"{2}\" height=\"{3}\"></embed></object><br/><a href=\"{1}\" target=\"_blank\" alt=\"Video\">{1}</a>";
        private static string FacebookCleanEmbedFormat = "<object width=\"{2}\" height=\"{3}\"><param name=\"allowfullscreen\" value=\"true\" /><param name=\"allowscriptaccess\" value=\"always\" /><param name=\"movie \" value=\"http://www.facebook.com/v/{0}\" /><embed src=\"http://www.facebook.com/v/{0}\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"{2}\" height=\"{3}\"></embed></object>";
        
        public static string GenerateCaptcha( this HtmlHelper helper )  
        {  
            var captchaControl = new Recaptcha.RecaptchaControl  
                    {  
                            ID = "recaptcha",
                            Theme = "clean",
                            PublicKey = "6LexdcASAAAAAFHoNhchdZpHlhbD7eyVXkgOWeWr",  
                            PrivateKey = "6LexdcASAAAAAO5hgSbaLfnJbFuLBtijZCmUy5rt" 
                };  
  
            var htmlWriter = new HtmlTextWriter( new StringWriter() );  
  
            captchaControl.RenderControl(htmlWriter);  
  
            return htmlWriter.InnerWriter.ToString();  
        }  

        public static string LinkOrText(this HtmlHelper helper, string text, string url)
        {
            return LinkOrText(helper, text, url, false);

        }

        public static string LinkOrText(this HtmlHelper helper, string text, string url, bool blankTarget)
        {
            if (String.IsNullOrEmpty(url))
                return helper.Encode(text);
            else
            {
                var a = new TagBuilder("a");
                a.Attributes.Add("href", helper.Encode(url));
                if (blankTarget)
                {
                    a.Attributes.Add("target", "_blank");
                }
                a.InnerHtml = helper.Encode(text);
                return a.ToString();
            }
        }

        public static string VideoUrl(this HtmlHelper helper, string url)
        {
            switch (GetVideoProvider(url))
            {

                // YouTube
                case VideoProvider.YouTube:
                    {
                        string youTubeId;
                        if (TryGetYouTubeVideoID(url, out youTubeId))
                            return string.Format(YoutubeUrlFormat, youTubeId);
                        break;
                    }

                case VideoProvider.Tinypic:
                    {
                        string tinypicId;
                        if (TryGetTinypicVideoID(url, out tinypicId))
                            return string.Format(TinypicUrlFormat, tinypicId);
                        break;
                    }

                // Default
                case VideoProvider.Unknown:
                default:
                    break;
            }
            return string.Empty;
        }

        public static string EmbedSmallVideo(this HtmlHelper helper, string url)
        {
            int width = 200;
            int height = 175;

            return EmbedVideo(helper, url, width, height, false, false);
        }


        public static string EmbedVideo(this HtmlHelper helper, string url)
        {
            return EmbedVideo(helper, url, false);
        }

        public static string EmbedVideo(this HtmlHelper helper, string url, bool autoplay)
        {
            int width = 425;
            int height = 344;

            return EmbedVideo(helper, url, width, height, true, autoplay);
        }

        public static VideoProvider GetVideoProvider(string url)
        {
            if (url.StartsWith("http://www.youtube.com") ||
                url.StartsWith("https://www.youtube.com") ||
                url.StartsWith("http://youtube.com") ||
                url.StartsWith("https://youtube.com") ||
                url.StartsWith("www.youtube.com") ||
                url.StartsWith("youtube.com"))
                return VideoProvider.YouTube;
            
            if (url.StartsWith("http://es.tinypic.com") ||
                url.StartsWith("https://es.tinypic.com") ||
                url.StartsWith("http://tinypic.com") ||
                url.StartsWith("https://tinypic.com") ||
                url.StartsWith("es.tinypic.com") ||
                url.StartsWith("tinypic.com"))
                return VideoProvider.Tinypic;

            if (url.StartsWith("http://facebook.com") ||
                url.StartsWith("https://facebook.com") ||
                url.StartsWith("http://www.facebook.com") ||
                url.StartsWith("https://www.facebook.com") ||
                url.StartsWith("www.facebook.com") ||
                url.StartsWith("facebook.com"))
                return VideoProvider.Facebook;

            return VideoProvider.Unknown;
        }

        public static string EmbedVideo(this HtmlHelper helper, string url, int width, int height, bool showLink, bool autoplay)
        {
            switch (GetVideoProvider(url))
            {

                //Youtube
                case VideoProvider.YouTube:
                    {
                        string youTubeId = null;
                        if (TryGetYouTubeVideoID(url, out youTubeId))
                        {
                            if (showLink)
                            {
                                if (autoplay)
                                    return string.Format(YoutubeEmbedAutoplayFormat, youTubeId, url, width, height);
                                else
                                    return string.Format(YoutubeEmbedFormat, youTubeId, url, width, height);
                            }
                            else
                                return string.Format(YoutubeCleanEmbedFormat, youTubeId, url, width, height);
                        }
                        return string.Format(BasicEmbedFormat, url);
                    }

                //Tinypic
                case VideoProvider.Tinypic:
                    {
                        string tinypicVideoId = null;
                        if (TryGetTinypicVideoID(url, out tinypicVideoId))
                        {
                            if (showLink)
                                return string.Format(TinypicEmbedFormat, tinypicVideoId, url, width, height);
                            else
                                return string.Format(TinypicCleanEmbedFormat, tinypicVideoId, url, width, height);
                        }
                        return string.Format(BasicEmbedFormat, url);
                    }

                //Facebook
                case VideoProvider.Facebook:
                    {
                        string facebookVideoId = null;
                        if (TryGetFacebookVideoID(url, out facebookVideoId))
                        {
                            if (showLink)
                                return string.Format(FacebookEmbedFormat, facebookVideoId, url, width, height);
                            else
                                return string.Format(FacebookCleanEmbedFormat, facebookVideoId, url, width, height);
                        }
                        return string.Format(BasicEmbedFormat, url);
                    }

                // Defaults
                case VideoProvider.Unknown:
                default:
                    return string.Format(BasicEmbedFormat, url);
            }

        }

        private static bool TryGetYouTubeVideoID(string youTubeUrl, out string youTubeId)
        {
            Match regexMatch = Regex.Match(youTubeUrl, "^[^v]+v=(.{11}).*", RegexOptions.IgnoreCase);

            if (regexMatch.Success)
            {
                youTubeId = regexMatch.Groups[1].Value;
                return true;
            }

            youTubeId = null;
            return false;
        }

        private static bool TryGetTinypicVideoID(string tinypicUrl, out string tinypicId)
        {
            return TryGetGenericVVideoID(tinypicUrl, out tinypicId);
        }

        private static bool TryGetFacebookVideoID(string facebookUrl, out string facebookId)
        {
            return TryGetGenericVVideoID(facebookUrl, out facebookId);
        }

        private static bool TryGetGenericVVideoID(string url, out string id)
        {
            Match regexMatch = Regex.Match(url, "v=([^&]+)*", RegexOptions.IgnoreCase);

            if (regexMatch.Success)
            {
                id = regexMatch.Groups[1].Value;
                return true;
            }

            id = null;
            return false;
        }

    }
}
